class_name AttributeManager
extends RefCounted

## 属性缓存
## { attribute_name-String: attribute-Attribute }
var _attribute_map: Dictionary


func add_attribute(attribute: Attribute) -> void:
	if attribute == null:
		Logger.warning("Added attribute can not be null.")
		return

	if _attribute_map.has(attribute.name):
		Logger.warning("Already has the attribute with given name '%s'." % attribute.name)
		return
	
	_attribute_map[attribute.name] = attribute


func add_attributes(attributes: Array[Attribute]) -> void:
	for attribute: Attribute in attributes:
		add_attribute(attribute)


func get_attribute(attribute_name: String) -> Attribute:
	var attribute = _attribute_map.get(attribute_name)
	if attribute == null:
		Logger.warning("No such attribute with given name '%s'." % attribute_name)
		return null
	else:
		return attribute


func apply_modifiers(effect_modifiers: Dictionary) -> void:
	if effect_modifiers == null or effect_modifiers.is_empty():
		Logger.warning("Null effect modifiers.")
		return
	
	var attribute = get_attribute(effect_modifiers["effect"].effect_asset.attribute_name)
	if not attribute:
		Logger.warning("No such attribute with given name '%s'." % effect_modifiers["attribute_name"])
		return
	
	var effect = effect_modifiers["effect"] as GameplayEffect

	# 当效果为立即触发或者周期性触发时，就需要同时修改 base_value 和 current_value
	# 当效果为持续性的时，只需要修改 current_value
	var modify_both =\
		not effect.effect_asset.has_component("DurationEffectComponent") or\
		effect.effect_asset.has_component("PeriodEffectComponent")
	
	for modifier in effect_modifiers["modifiers"]:
		var magnitude = modifier["magnitude"]
		match modifier["operation"]:
			GameplayEffectModifierAsset.Operation.Override:
				if modify_both:
					attribute.base_value = magnitude
				attribute.current_value = magnitude
			
			GameplayEffectModifierAsset.Operation.Add:
				if modify_both:
					attribute.base_value += magnitude
				attribute.current_value += magnitude
			
			GameplayEffectModifierAsset.Operation.Multiply:
				if modify_both:
					attribute.base_value *= magnitude
				attribute.current_value *= magnitude
